﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Core;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Web.Http;
using System.Web.Http.Filters;
using System.Web.Http.OData.Extensions;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using SalesSys.Comm.Utility;
using SalesSys.Site.Controllers;
using SalesSys.Site.Controllers.Api;
using SalesSys.WebCore;
using System.Threading.Tasks;

namespace SalesSys.Site
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务
            // 将 Web API 配置为仅使用不记名令牌身份验证。
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

           

            HttpConfiguration fConfig = config;
           fConfig.Formatters.Remove(fConfig.Formatters.JsonFormatter);
            fConfig.Formatters.Insert(0, new JsonExFormatter());
          
            //GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
            //    ReferenceLoopHandling.Ignore;
            //GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
            //    new Newtonsoft.Json.Converters.IsoDateTimeConverter()
            //    {
            //        DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
            //    });
        }
    }

    public class JsonExFormatter : MediaTypeFormatter
    {
         
        public JsonExFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
            SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true));
            SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true));  
              }
        public override bool CanReadType(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            return true;
        }
        public override bool CanWriteType(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            return true;
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            return Task.FromResult(this.DeserializeFromStream(type, readStream));
        }
        private object DeserializeFromStream(Type type, Stream readStream)
        {
            ISerializerHandle json = SimpleJson.CreateEx();
            return json.Deserialize(new StreamReader(readStream), type);
           
        }
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, TransportContext transportContext)
        {
            ISerializerHandle json = SimpleJson.CreateEx();
            var w = new StreamWriter(writeStream);
            json.Serialize(w, value, type);
            w.Flush();
            return Task.FromResult(writeStream);
        }
    }  
    public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
    {
        //重写基类的异常处理方法
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Exception is NotImplementedException)
            {
                actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
            }
            else if (actionExecutedContext.Exception is TimeoutException)
            {
                actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.RequestTimeout);
            }
            else
            {
                   var content =  actionExecutedContext.Exception;
                HttpResponseMessage respMsg=null;
                if (actionExecutedContext.Exception is EntityException)
                {
                    var msg = ReState.InternalError.CreateResult(actionExecutedContext.Exception.Message, content);
                    respMsg = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, msg);
                    respMsg.ReasonPhrase = ReState.InternalError.ToString();
                }
                else if (actionExecutedContext.Exception is ApiArgException)
                {
                    var msg = ReState.ArgError.CreateResult(actionExecutedContext.Exception.Message, content);
                    respMsg = actionExecutedContext.Request.CreateResponse(HttpStatusCode.BadRequest, msg);
                    respMsg.ReasonPhrase = ReState.ArgError.ToString();

                }
                actionExecutedContext.Response = respMsg;
            }
            //System.Data.Entity.Core.EntityCommandExecutionException ex;EntityException
          
            base.OnException(actionExecutedContext);
        }
    }
}
